home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / print / gs261sr1.zip / GSCHAR0.C < prev    next >
C/C++ Source or Header  |  1993-05-12  |  7KB  |  234 lines

  1. /* Copyright (C) 1991, 1992 Aladdin Enterprises.  All rights reserved.
  2.  
  3. This file is part of Ghostscript.
  4.  
  5. Ghostscript is distributed in the hope that it will be useful, but
  6. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  7. to anyone for the consequences of using it or for whether it serves any
  8. particular purpose or works at all, unless he says so in writing.  Refer
  9. to the Ghostscript General Public License for full details.
  10.  
  11. Everyone is granted permission to copy, modify and redistribute
  12. Ghostscript, but only under the conditions described in the Ghostscript
  13. General Public License.  A copy of this license is supposed to have been
  14. given to you along with Ghostscript so you can know your rights and
  15. responsibilities.  It should be in a file named COPYING.  Among other
  16. things, the copyright notice and this notice must be preserved on all
  17. copies.  */
  18.  
  19. /* gschar0.c */
  20. /* Composite font decoding for Ghostscript library */
  21. /****** DOESN'T WORK. DON'T TRY TO USE IT. ******/
  22. #include "gx.h"
  23. #include "gserrors.h"
  24. #include "gxfixed.h"
  25. #include "gxmatrix.h"            /* for gzstate.h */
  26. #include "gzstate.h"            /* must precede gzdevice */
  27. #include "gzdevice.h"            /* must precede gxchar */
  28. #include "gxdevmem.h"
  29. #include "gxchar.h"
  30. #include "gxfont.h"
  31.  
  32. /* Select the appropriate descendant of a font. */
  33. /* Free variables: fdepth, index, p. */
  34. #define select_descendant(pfont, pdata, n)\
  35.   if ( (n) >= pdata->encoding_size )\
  36.     return_error(gs_error_rangecheck);\
  37.   if ( fdepth >= max_font_depth - 1 )\
  38.     return_error(gs_error_invalidfont);\
  39.   pfont = pdata->FDepVector[pdata->Encoding[n]];\
  40.   penum->fstack[penum->fdepth = ++fdepth] = pfont;\
  41.   penum->index = index = p - penum->str
  42.  
  43. /* Define a structure for a (character code, font index) pair. */
  44. typedef struct {
  45.     uint fidx;
  46.     gs_char chr;
  47. } mapped_char;
  48.  
  49. /* Forward declarations */
  50. private int map_SubsVector(P4(const byte *, int, gs_type0_data *, mapped_char *));
  51.  
  52. /* Get the next character (to penum->chr) and font (to penum->pfont)
  53. /* from a composite string. */
  54. /* If we run off the end of the string in the middle of a */
  55. /* multi-byte sequence, return gs_error_rangecheck. */
  56. /* If the string is empty, return 1.  Otherwise, return 0. */
  57. int
  58. gs_type0_next(gs_show_enum *penum)
  59. {    uint index = penum->index;
  60.     const byte *p = penum->str + index;
  61.     uint size = penum->size;
  62.     int fdepth = 0;
  63.     gs_font *pfont = penum->fstack[0];
  64.     gs_type0_data *pdata;
  65.     mapped_char mc;
  66.     int code;
  67.     if ( size == index ) return 1;
  68. #define need_left(n)\
  69.   if ( size - index < n ) return_error(gs_error_rangecheck)
  70. top:    pdata = &pfont->data.type0_data;
  71. top1:    switch ( pdata->FMapType )
  72.        {
  73.     default:            /* can't happen */
  74.         return_error(gs_error_invalidfont);
  75.  
  76.         /* ------ Non-modal mappings ------ */
  77.  
  78.     case fmap_8_8:
  79.         need_left(2);
  80.         mc.fidx = *p++;
  81.         mc.chr = *p++;
  82.         break;
  83.  
  84.     case fmap_1_7:
  85.         mc.fidx = *p >> 7;
  86.         mc.chr = *p++ & 0x7f;
  87.         break;
  88.  
  89.     case fmap_9_7:
  90.         need_left(2);
  91.         mc.fidx = ((uint)*p << 1) + (p[1] >> 7);
  92.         mc.chr = p[1] & 0x7f;
  93.         p += 2;
  94.         break;
  95.  
  96.     case fmap_SubsVector:
  97.     {    int width = pdata->subs_width;
  98.         need_left(width);
  99.         code = map_SubsVector(p, width, pdata, &mc);
  100.         if ( code < 0 ) return code;
  101.         p += width;
  102.         break;
  103.     }
  104.  
  105.         /* ------ Modal mappings ------ */
  106.  
  107.     case fmap_escape:
  108.         if ( *p != pdata->EscChar ) goto same_mode;
  109.         need_left(2);
  110.         mc.fidx = p[1]; p += 2; goto cmode;
  111.  
  112.     case fmap_double_escape:
  113.         if ( *p != pdata->EscChar ) goto same_mode;
  114.         need_left(2);
  115.         if ( p[1] == *p )
  116.            {    need_left(3);
  117.             mc.fidx = p[2] + 256; p += 3; goto cmode;
  118.            }
  119.         mc.fidx = p[1]; p += 2; goto cmode;
  120.         /* Enter a mode. */
  121. cmode:        penum->fdepth = 1;
  122.         break;
  123.  
  124.     case fmap_shift:
  125.         if ( *p == pdata->ShiftIn ) mc.fidx = 0;
  126.         else if ( *p == pdata->ShiftOut ) mc.fidx = 1;
  127.         else goto same_mode;
  128.         select_descendant(pfont, pdata, mc.fidx);
  129.         goto top;
  130.  
  131.         /* Stay in the same mode. */
  132. same_mode:    for ( ; ; )
  133.         {    pfont = penum->fstack[++fdepth];
  134.             if ( pfont->FontType != ft_composite) break;
  135.             pdata = &pfont->data.type0_data;
  136.             if ( pdata->FMapType != fmap_escape )
  137.                 goto top1;    /* must be non-modal */
  138.         }
  139. /******        penum->chr = *p++;    ******/
  140.         penum->index = index + 1;
  141.         return 0;
  142.  
  143.        }
  144.  
  145.     /* Control continues here for non-modal mappings. */
  146. remap:    select_descendant(pfont, pdata, mc.fidx);
  147.     /****** WHERE DOES THE FOLLOWING COMMENT BELONG?? ******/
  148.     /* We pre-checked the encoding vector, so we know that */
  149.     /* fidx is now a legal subscript for FDepVector. */
  150.     if ( pfont->FontType == ft_composite )    /* must be non-modal */
  151.     {    pdata = &pfont->data.type0_data;
  152.         switch ( pdata->FMapType )
  153.         {
  154.  
  155.         case fmap_8_8:
  156.             need_left(1);
  157.             mc.fidx = mc.chr;
  158.             mc.chr = *p++;
  159.             break;
  160.  
  161.         case fmap_1_7:
  162.         case fmap_9_7:
  163.             need_left(1);
  164.             mc.fidx = mc.chr;
  165.             mc.chr = *p++ & 0x7f;
  166.             break;
  167.  
  168.         case fmap_SubsVector:
  169.         {    int width = pdata->subs_width;
  170.             /* It isn't clear what to use for the input */
  171.             /* to the mapping algorithm.... */
  172.             byte c[4];
  173.             int i = width;
  174.             while ( --i >= 0 )
  175.                 c[i] = (byte)mc.chr, mc.chr >>= 8;
  176.             code = map_SubsVector(c, width, pdata, &mc);
  177.             if ( code < 0 ) return code;
  178.             break;
  179.         }
  180.  
  181.         default:        /* can't happen */
  182.             return_error(gs_error_invalidfont);
  183.         }
  184.         goto remap;
  185.     }
  186.     penum->pfont = pfont;
  187. /******    penum->chr = mc.chr;    ******/
  188.     return 0;
  189. }
  190.  
  191. /* ------ Internal routines ------ */
  192.  
  193. /* Get the font index for a character from a SubsVector. */
  194. private int
  195. map_SubsVector(const byte *p, int width, gs_type0_data *pdata, mapped_char *pmc)
  196. {    uint subs_count = pdata->subs_size;
  197.     const byte *psv = pdata->SubsVector;
  198. #define subs_loop(subs_elt, width)\
  199.   while ( subs_count != 0 && chr >= (schr = subs_elt) )\
  200.     subs_count--, chr -= schr, psv += width;\
  201.   pmc->chr = chr; break
  202.     switch ( width )
  203.     {
  204.     default:        /* can't happen */
  205.         return_error(gs_error_invalidfont);
  206.     case 1:
  207.        {    byte chr = *p, schr;
  208.         subs_loop(*psv, 1);
  209.        }
  210.     case 2:
  211. #define w2(p) (((ushort)*p << 8) + p[1])
  212.        {    ushort chr = w2(p), schr;
  213.         subs_loop(w2(psv), 2);
  214.        }
  215. #undef w2
  216.     case 3:
  217. #define w3(p) (((ulong)*p << 16) + ((uint)p[1] << 8) + p[2])
  218.        {    ulong chr = w3(p), schr;
  219.         subs_loop(w3(psv), 3);
  220.        }
  221. #undef w3
  222.     case 4:
  223. #define w4(p)\
  224.   (((ulong)*p << 24) + ((ulong)p[1] << 16) + ((uint)p[2] << 8) + p[3])
  225.        {    ulong chr = w4(p), schr;
  226.         subs_loop(w4(psv), 4);
  227.        }
  228. #undef w4
  229. #undef subs_loop
  230.     }
  231.     pmc->fidx = pdata->subs_size - subs_count;
  232.     return 0;
  233. }
  234.